package com.compty.paint.manager;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.compty.core.framework.context.spring.SpringContextHolder;
import com.compty.core.hibernate.HibernateEntityDao;
import com.compty.core.page.Page;
import com.compty.core.utils.BeanComparator;
import com.compty.paint.domain.Bid;
import com.compty.paint.domain.BidRecord;
import com.compty.paint.domain.Goods;
import com.compty.paint.domain.Painter;
import com.compty.paint.domain.Painting;
import com.compty.paint.domain.support.BidClassificationByPainter;
import com.compty.security.domain.User;

public class BidManager  extends HibernateEntityDao<Bid>{
	
	private BidRecordManager bidRecordManager;
	private GoodsManager goodsManager;
	
	public static Map<Long,Bid> availableBidMap = new ConcurrentHashMap<Long, Bid>();
	
	@SuppressWarnings("unchecked")
	public void init(){
		
		String hql = "from Bid b where b.status = 1 and b.bid_status = 1 and b.audit_status = 2 and  b.beginTime <= ? and b.endTime > ? ";
		
		List list =  super.find(hql,Calendar.getInstance().getTime(),Calendar.getInstance().getTime());
		int len = list.size();
		for (int i=0; i < len;i++) {
			
			Bid bid = (Bid)list.get(i);
			
			Long current_bidrecord_id = bid.getCurrent_bidrecord_id();
			BidRecord  currentBidRecord = bidRecordManager.get(current_bidrecord_id);
			bid.setCurrentBidRecord(currentBidRecord);
			
			availableBidMap.put(bid.getId(), bid );
		}
	}
	
    public void save(Bid bid) {
        super.save(bid);
        availableBidMap.put(bid.getId(), bid);
    }
	
	/**
	 *@Todo:采用加锁模式获得Bid详细信息
	 *@CreateTime:2012-3-5 上午11:01:41
	 * @param bidId 拍品编号
	 */
	public Bid findById(Long bidId) {
		// TODO Auto-generated method stub
		if( bidId == null) return null;
		Bid bid = availableBidMap.get(bidId);
		if( bid != null){
			return bid;
		}
		Session session = getSession();
		String hqlStr = " from Bid as bid where id = :ID " ;
		Query query = session.createQuery(hqlStr);
		query.setLong("ID", bidId);
		query.setLockMode( "bid" ,LockMode.UPGRADE); 
		
		Object obj = query.uniqueResult();
		if( obj == null){
			return null;
		}else{
			bid = (Bid)obj;
			Long current_bidrecord_id = bid.getCurrent_bidrecord_id();
			BidRecord  currentBidRecord = bidRecordManager.get(current_bidrecord_id);
			bid.setCurrentBidRecord(currentBidRecord);
			
			return bid;
		}
	}

	/**
	 *@Todo:查询可用(在前台显示)的拍品列表
	 *@CreateTime:2012-3-7 上午11:32:46
	 * @param curPage 当前页码
	 * @param pageSize 当前页面显示条数
	 */
	@SuppressWarnings("unchecked")
	public Page queryBid_available(Integer curPage, Integer pageSize) {
		// TODO Auto-generated method stub
		String hql = "from Bid b where b.status = 1 and b.bid_status > 0 and b.audit_status = 2 and  b.beginTime <= ? "
			 		+ " order by b.id desc";
		Page page =  super.pagedQuery(hql, curPage, pageSize,Calendar.getInstance().getTime());
		Object result = page.getResult();
		if( result != null){
			List list = (List)result;
			int len = list.size();
			for (int i=0; i < len;i++) {
				
				Bid bid = (Bid)list.get(i);
				
				Long current_bidrecord_id = bid.getCurrent_bidrecord_id();
				BidRecord  currentBidRecord = bidRecordManager.get(current_bidrecord_id);
				bid.setCurrentBidRecord(currentBidRecord);
			}
		}
		
		return page;
	}
	
	/**
	 * 查询可用(在前台显示)的拍品列表,按艺术家分类显示
	 * @param curPage 当前页码
	 * @param pageSize 页面大小 
	 */
	@SuppressWarnings("unchecked")
	public Page queryBid_available_ClassificationByPainter(final Integer curPage, final Integer pageSize) {
		
		List list  =  (List)this.getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				
				String sql = "select a.painter_id from t_bid a,(select max(id) as id from t_bid group by painter_id )as b where a.id = b.id order by a.id desc";
				
				SQLQuery query = session.createSQLQuery(sql);
				query.setFirstResult((curPage-1)*pageSize);
				query.setMaxResults(pageSize);
				
				List list = query.addScalar("painter_id", Hibernate.LONG).list();
				
				return list;
			}
		});
		
		
		List<BidClassificationByPainter> bidClassificationByPainterList  =  new ArrayList<BidClassificationByPainter>();
		int size = list.size();
		for (int i = 0; i < size ; i++) {
			if(list.get(i) == null){
				continue;
			}
			Long painterId = (Long) list.get(i);
			
			BidClassificationByPainter bidClassificationByPainter = new BidClassificationByPainter();
			
			PainterManager painterManager = SpringContextHolder.getBean("painterManager");
			Painter painter = painterManager.get(painterId);
			
			List<Bid> bidList = findBidListByPainterId(painterId);
			if( bidList != null && bidList.size()>0){
				Bid bid = bidList.get(0);
				bidClassificationByPainter.setBid(bid);
			}
			if( bidList != null && bidList.size()>0){
				bidClassificationByPainter.setNewestBidList(bidList);
			}
			
			bidClassificationByPainter.setPainter(painter);
			
			bidClassificationByPainterList.add(bidClassificationByPainter);
		}
		
		Page page = new Page();
		page.setResult(bidClassificationByPainterList);
		page.setPageNo(curPage);
		page.setPageSize(pageSize);
		
		return page;
	}
	
	@SuppressWarnings("unchecked")
	public List<Bid> findBidListByPainterId(Long painterId){
		
		String hql = "from Bid where painter_Id= ? order by id desc";
		
		List list = super.find(hql, painterId);
		for (int i=0; list!=null && i < list.size();i++) {
			
			Bid bid = (Bid)list.get(i);
			
			Long current_bidrecord_id = bid.getCurrent_bidrecord_id();
			BidRecord  currentBidRecord = bidRecordManager.get(current_bidrecord_id);
			bid.setCurrentBidRecord(currentBidRecord);
			
			Date  endTime = bid.getEndTime();
			if(Calendar.getInstance().getTime().compareTo(endTime) < 0){
				bid.setNewFlag("1");
			}else{
				bid.setNewFlag("0");
			}
			
			Integer goods_id = bid.getGoods_id();
			if( goods_id != null){
				Goods goods = goodsManager.findById(goods_id);
				if( goods != null ){
					Painting painting = goods.getPainting();
					if( painting != null ){
						painting.getPainter().getImageInfo().getSuffix();
						bid.setGoods(goods);
					}
				}
			}
		}
		
		BeanComparator.sort(list,new String[]{"newFlag","id"}, -1);
		
		return list;
	}
	
	/**
	 * 查询结束竟拍未生成订单的拍品列表
	 */
	@SuppressWarnings("unchecked")
	public List<Bid> queryBid_end() {
		// TODO Auto-generated method stub
		String hql = "from Bid b where b.status = 1 and b.bid_status = 1 and b.audit_status = 2 and  b.endTime <= ? and b.beginTime < ?  "
			 		+ " order by b.id desc";
		List list = super.find(hql, Calendar.getInstance().getTime(),Calendar.getInstance().getTime());
		for (int i=0;list != null &&  i < list.size();i++) {
			Bid bid = (Bid)list.get(i);
			
			Long current_bidrecord_id = bid.getCurrent_bidrecord_id();
			if( current_bidrecord_id != null){
				BidRecord  currentBidRecord = bidRecordManager.get(current_bidrecord_id);
				bid.setCurrentBidRecord(currentBidRecord);
			}
		}
		
		return list;
	}
	
	/**
	 * 删除拍品及拍卖记录
	 * @param id 拍品ID
	 */
	public void removeById(Serializable id) {
		
		bidRecordManager.deleteByBidId(id);
		
		super.removeById(id);
	}
	
	/**
	 *@Todo:由作品ID查找拍品
	 *@author:朱庆辉
	 *@CreateTime:2012-3-15 上午11:29:13
	 * @param painting_id 作品ID
	 * @return
	 */
	public Bid findByPaintingId(Long painting_id) {
		// TODO Auto-generated method stub
		Goods goods = goodsManager.findByPaintingId(painting_id);
		if(goods != null){
			Integer goods_id = goods.getId();
			Bid bid = findUniqueBy("goods_id", goods_id);
			
			return bid;
		}
		return null;
	}

	public void setBidRecordManager(BidRecordManager bidRecordManager) {
		this.bidRecordManager = bidRecordManager;
	}

	public void setGoodsManager(GoodsManager goodsManager) {
		this.goodsManager = goodsManager;
	}

	/**
	 *@Todo:由id查找bid,包括缓存
	 *@author:朱庆辉
	 *@CreateTime:2012-3-30 下午08:58:06
	 * @param bidId
	 * @return
	 */
	public Bid getById(Long bidId) {
		// TODO Auto-generated method stub
		if( bidId == null) return null;
		
		Bid bid = super.get(bidId);
		Long current_bidrecord_id = bid.getCurrent_bidrecord_id();
		BidRecord  currentBidRecord = bidRecordManager.get(current_bidrecord_id);
		bid.setCurrentBidRecord(currentBidRecord);
		
		return bid;
	}

	/**
	 *@Todo:分页查询拍品信息
	 *@author:朱庆辉
	 *@CreateTime:2012-4-16 上午09:00:15
	 * @param curPage 当前页码 
	 * @param pageSize 页面显示条数
	 * @param userInfo 当前登录用户
	 * @param startDate 开始时间（录入时间）
	 * @param endDate 截止时间 （录入时间）
	 * @param filterTxt 字段名称
	 * @param filterValue 字段值
	 * @param bid_status 拍品状态 
	 * @return
	 */
	public Page queryBidForPage(Integer curPage, Integer pageSize,
			User userInfo, Date startDate, Date endDate, String filterTxt,String filterValue,String bid_status) {
		// TODO Auto-generated method stub
		   Criteria criteria =  super.createCriteria();
			  
	        criteria.addOrder(Order.desc("id"));
	        criteria = criteria.add(Restrictions.eq("status", 1));
	        if( bid_status != null && !"".equals(bid_status)){
	        	 criteria = criteria.add(Restrictions.eq("bid_status", bid_status));
	        }
	        
	        if(userInfo!= null && "0".equals(userInfo.getAdministratorFlag())){
	        	  criteria = criteria.add(Restrictions.eq("entryPerson", userInfo));
	        }
	        
	        if(startDate != null){
	        	 criteria = criteria.add(Restrictions.ge("uploadTime", startDate));
	        }
	        
	        if(endDate != null){
	        	 criteria = criteria.add(Restrictions.lt("uploadTime", endDate));
	        }

	        if ((filterTxt != null) && (filterValue != null)&& (!filterTxt.equals("")) && (!filterValue.equals(""))) {
	            criteria = criteria.add(Restrictions.like(filterTxt,
	                        "%" + filterValue + "%"));
	        }
	        
	        Page page = super.pagedQuery(criteria, curPage, pageSize);
	        
	        return page;
	}
	
	/**
	 *@Todo:根据商品ID删除拍品
	 *@author:朱庆辉
	 *@CreateTime:2012-4-6 下午01:52:33
	 * @param goodsId 商品ID
	 */
	@SuppressWarnings("unchecked")
	public void removeByGoodsId(Serializable goodsId) {
		
		String hql = "from  Bid where goods_id = ?";
		
		List<Bid>  list = find(hql, goodsId);
		
		for (Bid bid : list) {
			if( bid != null){
				removeById(bid.getId());
			}
		}
		
	}

	/**
	 * 
	 *@Todo:分页查询拍品信息
	 *@author:朱庆辉
	 *@CreateTime:2012-4-16 下午04:21:15
	 * @param curPage 当前页码 
	 * @param pageSize 页面显示条数
	 * @param userInfo 当前登录用户
	 * @param typeId 分类ID(油画、国画)
	 * @param startDate 开始时间（录入时间）
	 * @param endDate 截止时间 （录入时间）
	 * @param filterTxt 字段名称
	 * @param filterValue 字段值
	 * @return
	 */
	public Page queryBidForPageByCatalogType( final Integer curPage,final int pageSize,
			final User userInfo, final Integer typeId, final Date startDate,final Date endDate,
			final String filterTxt, final String filterValue) {
		// TODO Auto-generated method stub
		return (Page) this.getHibernateTemplate().execute(new HibernateCallback() {
			@SuppressWarnings("unchecked")
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				
				String sql = "select b.* from t_bid b,t_goods g,t_painting p where b.goods_id = g.id and g.painting_id = p.id ";
				
				if(typeId != null){
					sql += "  and p.catalogtype_id= " + typeId;
				}
				
				if(startDate != null){
					sql += " and b.uploadtime >= :startDate ";
				}
				
				if(endDate != null){
					sql += " and b.uploadtime < :endDate ";
				}
				
				sql += " order by b.id desc "; 
				
				SQLQuery query = session.createSQLQuery(sql);
				if(startDate != null){
					query.setParameter("startDate", startDate);
				}
				if(endDate != null){
					query.setParameter("endDate", endDate);
				}
				
				query.setMaxResults(pageSize);
				int start = (curPage - 1) * pageSize;
				query.setFirstResult(start);
				
				List list = query.addEntity(Bid.class).list();
				
				String count_sql = "select count(*) from t_bid b,t_goods g,t_painting p where b.goods_id = g.id and g.painting_id = p.id ";
				
				if(typeId != null){
					count_sql += "  and p.catalogtype_id= " + typeId;
				}
				
				if(startDate != null){
					count_sql += " and b.uploadtime >= :startDate ";
				}
				
				if(endDate != null){
					count_sql += " and b.uploadtime < :endDate ";
				}
				
				SQLQuery countquery = session.createSQLQuery(count_sql);
				if(startDate != null){
					countquery.setParameter("startDate", startDate);
				}
				if(endDate != null){
					countquery.setParameter("endDate", endDate);
				}
				
				int totalCount = ((Number)countquery.uniqueResult()).intValue();
				
				Page page = new Page(list, totalCount);
		        page.setPageNo(curPage);
		        page.setPageSize(pageSize);
			        
			    return page;
			}
		});
		
	}

}
